package com.glela.platform.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.glela.cache.model.RedisKey;
import com.glela.cache.redis.RedisUtil;
import com.glela.common.constant.UserMoenyTypeEnum;
import com.glela.common.model.sms.SMSWalletDrawMoney;
import com.glela.common.service.SMSService;
import com.glela.common.util.DateUtil;
import com.glela.common.util.DateUtils;
import com.glela.common.util.NumberUtil;
import com.glela.platform.constant.ErrorEnum;
import com.glela.platform.mapper.OperationLogMapper;
import com.glela.platform.mapper.UserBankMapper;
import com.glela.platform.mapper.UserJournalMapper;
import com.glela.platform.mapper.UserMapper;
import com.glela.platform.mapper.UserMoneyMapper;
import com.glela.platform.model.Bank;
import com.glela.platform.model.BaseRestrictions;
import com.glela.platform.model.MoneyBusinessType;
import com.glela.platform.model.OperationLog;
import com.glela.platform.model.PushMessage;
import com.glela.platform.model.User;
import com.glela.platform.model.UserBank;
import com.glela.platform.model.UserMoney;
import com.glela.platform.model.response.ResponseBankModel;
import com.glela.platform.model.response.ResponseBaseModel;
import com.glela.platform.model.response.ResponsePageModel;
import com.glela.platform.model.response.ResponseResultModel;
import com.glela.platform.model.response.ResponseUserBank;
import com.glela.platform.model.response.ResponseUserBankAndMoney;
import com.glela.platform.service.BaseRestrictionsService;
import com.glela.platform.service.MoneyBusinessTypeService;
import com.glela.platform.service.PushMessageService;
import com.glela.platform.service.UserBankService;
import com.glela.platform.service.UserJournalService;
import com.glela.platform.service.UserMoneyService;
import com.glela.usermoney.mapper.UserCommisionMapper;
import com.glela.usermoney.model.UserCommision;

@Service("userBankService")
@Scope("singleton")
public class UserBankServiceImpl implements UserBankService {
	@Autowired
	private SMSService smsService;
	@Autowired
	private UserBankMapper userBankMapper;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private UserJournalMapper userJournalMapper;
	@Autowired
	private MoneyBusinessTypeService moneyBusinessTypeService;
	@Autowired
	private BaseRestrictionsService baseRestrictionsService;
	@Autowired
	private UserMoneyMapper userMoneyMapper;
	@Autowired
	private UserMoneyService userMoneyService;
	@Autowired
	private UserCommisionMapper userCommisionMapper;
	@Autowired
	private OperationLogMapper operationLogMapper;
	@Autowired
	private UserJournalService userJournalService;
	@Autowired
	private PushMessageService pushMessageService;
	@Autowired
	private RedisUtil redisUtil;
	private static Logger logger = LoggerFactory.getLogger(UserBankServiceImpl.class);
	/**
	 * 获取合作的银行
	 */
	@Override
	public ResponseEntity<?> getBankLst() {
		// TODO Auto-generated method stub
		List<Bank> bankList = userBankMapper.selectBankList();
		List<ResponseBankModel> resModel = new ArrayList<ResponseBankModel>();
		for (Bank bank : bankList) {
			ResponseBankModel res = new ResponseBankModel();
			res.setBankId(bank.getId());
			res.setBankName(bank.getBankName());
			res.setIcon(bank.getIcon());
			resModel.add(res);
		}
		ResponsePageModel<ResponseBankModel> pageList = new ResponsePageModel<>(bankList.size(), resModel);
		return new ResponseEntity<>(new ResponseResultModel<>(pageList), HttpStatus.OK);
	}

	/**
	 * 查询银行卡列表
	 */
	@Override
	public ResponseEntity<?> listUserBankPage(Long userId, int page, int pageSize) {
		// TODO Auto-generated method stub
		List<UserBank> bankCardList = userBankMapper.selectUserBankPage(userId, page, pageSize);
		List<Bank> bankList = userBankMapper.selectBankList();
		List<ResponseUserBank> resList = new ArrayList<ResponseUserBank>();
		for (UserBank bankCard : bankCardList) {
			ResponseUserBank resBank = new ResponseUserBank();
			for (Bank bank : bankList) {
				if (bankCard.getBankId() == bank.getId()) {
					resBank.setBankName(bank.getBankName());
					resBank.setIcon(bank.getIcon());
				}
			}
			resBank.setBanKId(bankCard.getId());
			resBank.setName(bankCard.getName());
			resBank.setUserId(bankCard.getUserId());
			resBank.setBankCard(bankCard.getBankCard());
			resBank.setBankBranchName(bankCard.getBankBranchName());
			resList.add(resBank);
		}
		int count = userBankMapper.selectUserBankcount(userId);
		ResponsePageModel<ResponseUserBank> pageList = new ResponsePageModel<>(count, resList);
		return new ResponseEntity<>(new ResponseResultModel<>(pageList), HttpStatus.OK);
	}

	/**
	 * 删除银行卡
	 * 
	 * @throws Exception
	 */
	@Override
	public ResponseEntity<?> removeUserBankById(Long userId, int cardId) throws Exception {
		// TODO Auto-generated method stub
		int delStatus = userBankMapper.deleteUserBankById(userId, cardId);
		if (delStatus <= 0) {
			throw new Exception();
		}
		return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C10000), HttpStatus.OK);
	}

	/**
	 * 新增银行卡
	 * 
	 * @throws Exception
	 */
	@Override
	public ResponseEntity<?> addUserBank(Long userId, String name, String bankCard, 
			int bankId, String bankBranchName, int bankBranchId, String idNumber)
			throws Exception {
		//去除空格
		bankCard = bankCard.replaceAll("\\s*", "");
		name = name.replaceAll("\\s*", "");
		idNumber = StringUtils.isNotBlank(idNumber)?idNumber.replaceAll("\\s*", ""):"";
		
		UserBank bancCardStatus = userBankMapper.selectBankByCardNo(bankCard);
		if (bankId == 2088) {
			UserBank aliStatus = userBankMapper.selectUserBankAli(userId);
			if (aliStatus != null) {
				userBankMapper.updateUserAliInfo(name,bankCard,userId);
				return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C10000), HttpStatus.OK);
			}
		} else {
			if (bankBranchName == null && "".equals(bankBranchName)) {
				return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C29903), HttpStatus.OK);
			}
		}
		
		Bank bank = userBankMapper.selectBankById(bankId);
		
		if (bancCardStatus != null) {
			if (bancCardStatus.getUserId().intValue() != userId.intValue()) {
				return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20178), HttpStatus.OK);
			}
			if (bancCardStatus.getStatus() == 0) {
				userBankMapper.updateUserBankStatus(1, bancCardStatus.getId());
				return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C10000), HttpStatus.OK);
			} else {
				return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20166), HttpStatus.OK);
			}
		}
		int addStatus = userBankMapper.insertUserBank(userId, name, bankCard, bank.getId(), bankBranchName, bank.getBankName(),bankBranchId,idNumber);
		if (addStatus <= 0) {
			throw new Exception();
		}
		return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C10000), HttpStatus.OK);
	}

	/**
	 * 用户提现
	 * 
	 * @author gaoweiqi
	 * @date 2018年04月12日 12:44:05
	 * @throws Exception
	 */
	@Override
	public synchronized ResponseEntity<?> userDrawings(Long userId, int money, int bankId) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String time = sdf.format(new Date());// 当前时间(用于作为插入提现记录的时间)
		// 账户核算时间
		BaseRestrictions base = baseRestrictionsService.getBaseRestrictionsForCache("NoAllowedWithUserMoney");
		if (base != null && base.getStatus() == 1) {// 设置了维护时间
			String str[] = StringUtils.split(base.getName(), "~");
			if (DateUtil.betweenTime(str[0], str[1], DateUtil.currentYourDate("HH:mm:ss"), "HH:mm:ss") == 1) {
				return new ResponseEntity<>(
						new ResponseBaseModel(ErrorEnum.C20277, "小铺正在计算收益，期间暂停提现。时间：" + base.getName()), HttpStatus.OK);
			}
		}
		// redis记录 防止重复提交 申请
		if (redisUtil.exists(RedisKey.USER_DRAWINGS + userId, RedisKey.USER_MONEY_DBINDEX)) {
			String KeyValue = redisUtil.hmget(RedisKey.USER_DRAWINGS + userId,
					userId + ":" + money + ":" + bankId + ":" + time, RedisKey.USER_MONEY_DBINDEX);
			if (StringUtils.isBlank(KeyValue)) {
				redisUtil.hmset(RedisKey.USER_DRAWINGS + userId, userId + ":" + money + ":" + bankId + ":" + time,
						"1", RedisKey.USER_MONEY_DBINDEX);
			} else {
				redisUtil.hincrBy(RedisKey.USER_DRAWINGS + userId, userId + ":" + money + ":" + bankId + ":" + time,
						1, RedisKey.USER_MONEY_DBINDEX);
				logger.error("用户重复申请提现: id:{} time:{} money:{}", userId, time, money);
				return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20277), HttpStatus.OK);
			}
		} else {
			redisUtil.hmset(RedisKey.USER_DRAWINGS + userId, userId + ":" + money + ":" + bankId + ":" + time, "1",
					RedisKey.USER_MONEY_DBINDEX);
		}
		// 基本信息验证
		if(userMapper.selectUserEntityById(userId)==null){
			//用户不存在
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20113), HttpStatus.OK);
		}
		//------------新增五分钟之内同一用户只允许提现一次-------------------------------------------//
		//记录请求的系统时间
		long currentTimeMillis = new Date().getTime();
		Map<String ,Object> dMap  = userBankMapper.selectUserDrawingsNewByUserId(userId);
		if (null != dMap  &&  !dMap.isEmpty()) {
			long cTime = sdf.parse(dMap.get("create_time").toString()).getTime();
			if (currentTimeMillis - cTime < 5*60*1000) {//小于5分钟
				return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20174), HttpStatus.OK);
			}
		}
		List<UserMoney>  userMoney=userMoneyMapper.selectAllByUserIdAndType(userId, 1);//查找账户余额

		if(userMoney!=null&&userMoney.size()>1){
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20173), HttpStatus.OK);
		}
		UserMoney userM=userMoney.get(0);//获取账户余额
		//核算正负向流水是否正确
		int  Income= userJournalMapper.getUserJournalTotalIncome(userId);
		int  Spending=userJournalMapper.getUserJournalTotalSpending(userId);
		
		if(Income-Spending!=userM.getNormalAmount()+userM.getFrozenAmount()){
			//正负向流水不对
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20173), HttpStatus.OK);
		}
		if (userM.getNormalAmount() - money < 0) {
			// 申请时如果金额减去余额小于0时则余额不足
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20125), HttpStatus.OK);
		}
		
		int limitMoney = this.baseRestrictionsService
				.getBaseRestrictionsForCache("commision_limit").getRestrictions();
		//未达到提现标准
		if (userM.getNormalAmount() < limitMoney) {
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20165), HttpStatus.OK);
		}
		//未达提现最低标准
		if (money < limitMoney) {
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20171), HttpStatus.OK);
		}
		   //验证结束 开始提现动作(余额事务表中添加记录，同时用户可用减少，增加冻结)
		
		MoneyBusinessType businessType=moneyBusinessTypeService.selectMoneyBusinessByTypeId(11);//用户提现
		//添加提现事务信息
		if(businessType==null){
			//未找到相应类型
			return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C20273), HttpStatus.OK);
		}
		//扣减余额 增加冻结
		int updateStatus =userMoneyService.freezeUserMoneyAndType(userId, money,UserMoenyTypeEnum.C1.getCode());
		if (updateStatus <= 0) {
			throw new Exception();
		}
		//记录提现（新）---------------------zhangrenjie----------2017-09-08
		int insertStatus1 = 0;
		UserBank bank =  userBankMapper.queryUserBankByPrimaryId(bankId);
		if (null != bank) {
			//插入提现记录
			insertStatus1 = userBankMapper.insertUserDrawingsNew(userM.getUserId(),"",money,bankId,"用户提现:" + money,3,"-",0
			,bank.getBankName(),bank.getName(),bank.getBankCard(),bank.getBankBranchName(),time);
		}
		if (insertStatus1 <= 0) {
			throw new Exception("未找到该提现账户的信息");
		}
		//同时插入余额事物
		UserCommision userCommision = new UserCommision();
		userCommision.setOrderDetailId(0L);
		userCommision.setOrderInfoId(0L);
		userCommision.setOrderObjectId(0L);
		userCommision.setBusinessTypeId(businessType.getTypeId());
		userCommision.setBusinessTypeName(businessType.getTypeName());
		userCommision.setComment(businessType.getTypeDesc());
		userCommision.setUserId(userM.getUserId());
		userCommision.setFee(0-money);
		userCommision.setResult(0);//未处理结果状态
		userCommision.setIsCustom(0);//是否手工
		Map<String, Object> map = null;
		//按照创建时间查询最新一条记录提现记录
		map =  userBankMapper.queryUserDrawingsByCreateTime(userM.getUserId(),bankId,money,0,time,"-");
		if (!map.isEmpty() && null != map) {
			userCommision.setSourceId((Long)map.get("id"));//源提现记录主键ID
		}
		int i = userCommisionMapper.insertSelective(userCommision);
		if (i <= 0) {
			throw new Exception();
		}
         //提现申请成功 添加通知信息
	    //1. 发送短信
		//		String smsUrl = baseRestrictionsService.getBaseRestrictionsForCache("sendSms_url").getName();
		//		String account = baseRestrictionsService.getBaseRestrictionsForCache("sendSms_account").getName();
		//		String pwd = baseRestrictionsService.getBaseRestrictionsForCache("sendSms_pwd").getName();
		String date = DateUtils.dateFormat(new Date(), "yyyy-MM-dd HH:mm:ss");
	   //购买用户的昵称
	 User user = userMapper.selectByPrimaryKey(userId);
	 String bankCardName="";
	 if(bank.getBankId()==2088){
		 //bankCardName=bank.getBankCard().substring(0,4);
		 bankCardName= StringUtils.substring(bank.getBankCard(), 0, 4);
	 }else{
		 //bankCardName=bank.getBankCard().substring(bank.getBankCard().length()-4);
		 bankCardName=StringUtils.substring(bank.getBankCard(),bank.getBankCard().length()-4);
	 }
		//	String msg = URLEncoder.encode("您申请了一笔 " + money / 100.0 + " 元的提现,提现到 " + bank.getBankName() + "(" + bankCardName + ") " + bank.getName() + " ，如非本人申请操作请立即联系客服" + "，申请提现时间：" + date + "。【校妆网】", "UTF-8");
		//	SmsContents contents = new  SmsContents(account, pwd, user.getUserName(), msg);
		//	String code = HttpUtil.doPost(contents.toString(),smsUrl, "application/x-www-form-urlencoded");
		//	String resultInfo = SmsContentsError.checkCode(code);

		SMSWalletDrawMoney sms = new SMSWalletDrawMoney(user.getUserName());
		sms.setDrawMoney(NumberUtil.getFloatPrice(money));
		sms.setBankName(bank.getBankName());
		sms.setBankCardNo(bankCardName);
		sms.setAccountName(bank.getName());
		sms.setCreateTime(date);
		Object resultInfo = smsService.walletDrawMoney(sms);

	//短信日志
	OperationLog log = new OperationLog();
	log.setObjId(user.getId().intValue());
	log.setObjName(String.valueOf(user.getNickName()));
	log.setModule("userDrawings");
	log.setOperateType("sendSms");
	Long createLongTime = ((new Date().getTime()) / 1000);
	log.setCreatedAt(createLongTime.intValue());
	log.setDescription("申请提现发送短信给店主，店主电话"+user.getUserName()+"提现事务ID:"+userCommision.getId()+"。返回信息:"+resultInfo);
	operationLogMapper.insert(log);
	
		//2. 消息推送
			PushMessage pushMessage = new PushMessage();
			pushMessage.setIsAll(0);
			pushMessage.setUserId(userId);
			pushMessage.setStatus(1);//0禁用  1待发送  2已发送  3发送失败
			pushMessage.setTitle("申请提现成功");
			pushMessage.setContent("您的提现申请："+money/100.0+" 元 已受理，提现到 "+bank.getBankName()
					+"("+bankCardName+") "+bank.getName()
					+" ,正在审核中。");
			pushMessage.setType(1);//0系统消息 1钱包消息 2物流消息
			pushMessageService.autoPushMessage(pushMessage);	
	
		return new ResponseEntity<>(new ResponseBaseModel(ErrorEnum.C10000), HttpStatus.OK);
	}

	/**
	 * update by MaoZeYao Insert limitMoney
	 */
	@Override
	public ResponseEntity<?> getUserBankAndMoney(Long userId) {
		// TODO Auto-generated method stub
		ResponseUserBankAndMoney bankAndMoney = new ResponseUserBankAndMoney();
		UserBank userBank = userBankMapper.selectUserBankByIdLimitOne(userId);
		List<Bank> bankList = userBankMapper.selectBankList();
//		User user = userMapper.selectUserEntityByIdNoPassword(userId);
		// 用户余额金额
		long myMoney = this.userJournalService.getUserMoneyByUserIdAndType(userId, 1).getNormalAmount();
		bankAndMoney.setMoney(myMoney);
		if (userBank == null) {
			return new ResponseEntity<>(new ResponseResultModel<ResponseUserBankAndMoney>(bankAndMoney), HttpStatus.OK);
		}
		int limitMoney = userBankMapper.selectUserAdvanceLimit();
		ResponseUserBank resBank = new ResponseUserBank();
		for (Bank bank : bankList) {
			if (userBank.getBankId() == bank.getId()) {
				resBank.setBankName(bank.getBankName());
				resBank.setIcon(bank.getIcon());
			}
		}
		resBank.setBanKId(userBank.getId());
		resBank.setName(userBank.getName());
		resBank.setUserId(userBank.getUserId());
		resBank.setBankCard(userBank.getBankCard());
		resBank.setBankBranchName(userBank.getBankBranchName());
		bankAndMoney.setBankCard(resBank);
		bankAndMoney.setLimitMoney(limitMoney);
		return new ResponseEntity<>(new ResponseResultModel<ResponseUserBankAndMoney>(bankAndMoney), HttpStatus.OK);
	}

	/**
	 * 查询支付宝账号
	 */
	@Override
	public ResponseEntity<?> getUserBankAli(long userId) {
		// TODO Auto-generated method stub
		ResponseUserBank resModel = new ResponseUserBank();
		UserBank aliStatus = userBankMapper.selectUserBankAli(userId);
		
		if (aliStatus != null) {
			resModel.setBanKId(aliStatus.getId());
			resModel.setUserId(userId);
			resModel.setName(aliStatus.getName());
			resModel.setBankCard(aliStatus.getBankCard());
			resModel.setType(1);
		} else {
			resModel.setType(0);
		}
		
		return new ResponseEntity<>(new ResponseResultModel<>(resModel), HttpStatus.OK);
	}

}
